package com.smallnico.opencv;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;

public class Test3 {

	public static void main(String[] args) throws IOException, TesseractException {

		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

		String outPath = "C:\\Users\\ainil\\Desktop\\test_out.jpg";
		String originalImgPath1 = "C:\\Users\\ainil\\Desktop\\20180419152946919.png";
		String originalImgPath = "C:\\Users\\ainil\\Desktop\\1.png";
		String testDir = "C:\\Users\\ainil\\Desktop\\opencv-test\\";
		
		File file = new File(originalImgPath);
		BufferedImage textImage = ImageIO.read(file);
		int index = 1;

		Mat src = Imgcodecs.imread(originalImgPath);
		Mat dst = src.clone();

		List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
		Mat hierarchy = new Mat();

		cvWhite(dst);
		Imgproc.cvtColor(dst, dst, Imgproc.COLOR_BGR2GRAY);
		Imgproc.adaptiveThreshold(dst, dst, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C,
				Imgproc.THRESH_BINARY_INV, 11, 3);

		Imgproc.findContours(dst, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE,
				new Point(0, 0));
		
		//昵称
//		Mat nicknameMat = src.colRange(80, 500).rowRange(80, 160);
//		String imgPath = testDir + (index ++) + ".jpg";
//		Imgcodecs.imwrite(imgPath, nicknameMat);
////		String word = discernWord(textImage, new Rectangle(90, 80, 420, 80));
//		String word = discernWord(imgPath);
//		System.out.println("对方昵称:" + word.trim());
		
		int targetCount = 0;
		for (int i = contours.size() - 1; i >= 0; i--) {
			MatOfPoint point = contours.get(i);
			targetCount ++;
			//				System.out.println(point.toList());
			//			System.out.println(point.rows() + "-" + point.cols());
			//			Imgproc.drawContours(src, contours, i, new Scalar(0, 0, 0, 0), 1);
			//找矩形
			Rect rec = Imgproc.boundingRect(contours.get(i));
			int ran = 130;
			if (rec.height > 100 && rec.x > ran && rec.x < textImage.getWidth() - ran){
				if(rec.height == rec.width) {
					continue;
				}

				Mat newMat = src.colRange(rec.x + 20, rec.x + rec.width - 22).rowRange(rec.y, rec.y + rec.height);
				boolean isRight = isRight(newMat);
				String identify = "对方";
				if(isRight) {
					identify = "我";
				}
				int in = index ++;
				String imgPath = testDir + in + ".jpg";
//				Imgproc.cvtColor(newMat, newMat, Imgproc.COLOR_BGR2GRAY);
//				Imgproc.adaptiveThreshold(newMat, newMat, 244, Imgproc.ADAPTIVE_THRESH_MEAN_C,
//						Imgproc.THRESH_BINARY, 3, 3);
//				cvBW(newMat);
//				Imgproc.medianBlur(newMat, newMat, 1);
//				Imgproc.blur(newMat, newMat, new Size(3,3), new Point(-1, -1), Core.BORDER_DEFAULT);
//				Imgproc.GaussianBlur(newMat, newMat, new Size(3,3), 0, 0, Core.BORDER_DEFAULT);
				
				handleMat(newMat, in);
				
				Imgcodecs.imwrite(imgPath, newMat);
				
				
//				word = discernWord(textImage, new Rectangle(rec.x + 20, rec.y, rec.width - 30, rec.height));
				String word = discernWord(imgPath);
				System.out.println(identify + "：" + word.trim());
				System.out.println();
				
				Imgproc.rectangle(src, rec, new Scalar(0, 0, 0, 0));
			}
			
			
//			Imgproc.rectangle(src, rec, new Scalar(0, 0, 0, 0));

		}
		
		
		
		Imgcodecs.imwrite(outPath, src);
		System.out.println("finished");
	}

	private static void cvWhite(Mat dst) {
		int num=0;
		int num_rows = dst.rows();
		int num_col = dst.cols();
		for (int i = 0; i < num_rows; i++) {
			for (int j = 0; j < num_col; j++) {
				// 获取每个像素
				double[] clone = dst.get(i, j).clone();
				double hun = clone[0]; // HSV hun
				
				if (hun > 240) {
					if (clone[1] > 240) {
						if (clone[2] > 240) {
							// 红色范围,全部设置为黑色,
							clone[0] = 149;
							clone[1] = 236;
							clone[2] = 105;
							num++;
							dst.put(i, j, clone);
						}
					}
				}
				
			}
		}
	}
	
	private static void cvBW(Mat dst) {
		int num=0;
		int num_rows = dst.rows();
		int num_col = dst.cols();
		for (int i = 0; i < num_rows; i++) {
			for (int j = 0; j < num_col; j++) {
				double[] clone = dst.get(i, j).clone();
				double hun = clone[0]; // HSV hun
				int f = 60;
				if (hun > f) {
					if (clone[1] > f) {
						if (clone[2] > f) {
							clone[0] = 255;
							clone[1] = 255;
							clone[2] = 255;
							num++;
							dst.put(i, j, clone);
							continue;
						}
					}
				}
				clone[0] = 0;
				clone[1] = 0;
				clone[2] = 0;
				num++;
				dst.put(i, j, clone);
				continue;
			}
		}
	}
	
	private static boolean isRight(Mat img) {
		int num_rows = img.rows();
		int num_col = img.cols();
		int whiteCount = 0;
		int otherCount = 0;
		for (int i = 0; i < num_rows; i++) {
			for (int j = 0; j < num_col; j++) {
				// 获取每个像素
				double[] clone = img.get(i, j).clone();
				double hun = clone[0]; // HSV hun

				if (hun > 240) {
					if (clone[1] > 240) {
						if (clone[2] > 240) {
							whiteCount ++;
							continue;
						}
					}
				}
				otherCount ++;
			}
		}
		return otherCount > whiteCount;
	}
	
	private static void handleMat(Mat mat, int index) throws IOException, TesseractException {
		List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
		Mat hierarchy = new Mat();

		Mat dst = mat.clone();

		cvWhite(dst);
		Imgproc.cvtColor(dst, dst, Imgproc.COLOR_BGR2GRAY);
		Imgproc.adaptiveThreshold(dst, dst, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C,
				Imgproc.THRESH_BINARY_INV, 11, 3);
		Imgproc.GaussianBlur(dst, dst, new Size(5, 5), 5, 5, 4);
		
		Imgproc.findContours(dst, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE,
				new Point(0, 0));
		
		for (int i = contours.size() - 1; i >= 0; i--) {
			Rect rec = Imgproc.boundingRect(contours.get(i));
			Mat newMat = mat.colRange(rec.x, rec.x + rec.width).rowRange(rec.y, rec.y + rec.height);
			
			String path = "C:\\Users\\ainil\\Desktop\\opencv-test\\test" + index + "-" + i + ".jpg";
			Imgcodecs.imwrite(path , newMat);
			String words = discernWord(path);
			System.out.println("###" + words);
			Imgproc.rectangle(mat, rec, new Scalar(0, 0, 0, 0));
			
		}
		String path = "C:\\Users\\ainil\\Desktop\\opencv-test1\\test" + index + ".jpg";
		Imgcodecs.imwrite(path , mat);
	}
	
	
	public static String discernWord(BufferedImage image, Rectangle rect) throws IOException, TesseractException {
		Tesseract instance = new Tesseract();
		instance.setDatapath("E:\\Tesseract-OCR-4\\tessdata");// 设置语言库
		instance.setLanguage("chi_sim+eng");// 中文识别
		instance.setTessVariable("chop_enable","T");
		instance.setTessVariable("use_new_state_cost","F");
		instance.setTessVariable("segment_segcost_rating","F");
		instance.setTessVariable("enable_new_segsearch","0");
		instance.setTessVariable("language_model_ngram_on","0");
		instance.setTessVariable("textord_force_make_prop_words","F");
		String words = null;
//		words = instance.doOCR(textImage);
		instance.setPageSegMode(11);
		words = instance.doOCR(image, rect);
		
		
		return words;
	}
	
	public static String discernWord(String filePath) throws IOException, TesseractException {
		File file = new File(filePath);
		BufferedImage textImage = ImageIO.read(file);
		
		
		return discernWord(textImage, new Rectangle(0, 0, textImage.getWidth(), textImage.getHeight()));
	}
	
}
